package com.cyf.common.core.exception;

import java.util.ArrayList;
import java.util.List;

/**
 * @author chenyifan
 * @create 2024-10-14 10:54
 */
public class ExceptionUtil {

    /**
     * 获取异常链上所有异常的集合
     * @param throwable 异常对象
     * @return 异常链中所有异常集合
     */
    public static List<Throwable> getThrowableList(Throwable throwable) {
        List<Throwable> list = new ArrayList<>();
        while (throwable != null && !list.contains(throwable)) {
            list.add(throwable);
            throwable = throwable.getCause();
        }
        return list;
    }

    /**
     * 获取异常链中最尾端的异常，即异常最早发生的异常对象。
     * @param throwable 异常对象，可能为null
     * @return 最尾端异常
     */
    public static Throwable getRootCause(Throwable throwable) {
        List<Throwable> list = getThrowableList(throwable);
        return list.isEmpty() ? null : list.get(list.size() - 1);
    }

    /**
     * 获取异常链中最尾端的异常的消息
     * @param throwable 异常
     * @return 消息
     */
    public static String getRootCauseMessage(Throwable throwable) {
        Throwable root = getRootCause(throwable);
        return root == null ? null : root.getMessage();
    }

    /**
     * 获取异常链中指定类型的异常对象
     * @param throwable 异常
     * @param clazz 要查找的异常类型
     * @return
     */
    public static Throwable getThrowableOfType(Throwable throwable, Class<?> clazz) {
        List<Throwable> list = getThrowableList(throwable);
        for (Throwable t : list) {
            if (clazz.isAssignableFrom(t.getClass())) {
                return t;
            }
        }
        return null;
    }
}
